package com.github.base.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.crypto.symmetric.AES;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.base.domain.Dept;
import com.github.base.domain.User;
import com.github.base.domain.UserRole;
import com.github.base.dto.user.UserAddDTO;
import com.github.base.dto.user.UserListDTO;
import com.github.base.dto.user.UserUpdateDTO;
import com.github.base.exception.CommonException;
import com.github.base.global.Const;
import com.github.base.mapper.DeptMapper;
import com.github.base.mapper.UserMapper;
import com.github.base.service.UserRoleService;
import com.github.base.service.UserService;
import com.github.base.vo.user.UserInfoVO;
import com.github.base.vo.user.UserListVO;
import com.github.base.vo.user.UserRoleVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 账号
 * @author: dongdong.wen
 * @date: 2021/1/28 8:12 下午
 **/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private DeptMapper deptMapper;

    @Value("${aes.key:aaaaaaaaaaaaaaaa}")
    private String aesKey;

    /**
     * 添加用户信息
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(UserAddDTO dto) {
        Long count = userMapper.selectCount(Wrappers.lambdaQuery(User.class)
                .eq(User::getUsername, dto.getUsername())
                .eq(User::getState, Const.YES));
        if (count > 0) {
            throw new CommonException("账号已存在");
        }
        Dept dept = deptMapper.selectOne(Wrappers.lambdaQuery(Dept.class)
                .eq(Dept::getId, dto.getDeptId())
                .eq(Dept::getState, Const.YES));
        if (StrUtil.isBlankIfStr(dept)) {
            throw new CommonException("所属部门不存在");
        }
        // 添加用户信息
        User user = BeanUtil.copyProperties(dto, User.class);
        user.setCreateTime(LocalDateTime.now());
        String password = dto.getPassword();
        AES aes = SecureUtil.aes(aesKey.getBytes(CharsetUtil.CHARSET_UTF_8));
        String s = aes.decryptStr(password, CharsetUtil.CHARSET_UTF_8);
        String pwd = BCrypt.hashpw(s);
        user.setPassword(pwd);
        user.setModifyTime(LocalDateTime.now());
        user.setOperable(Const.YES);
        user.setState(Const.YES);
        user.insert();
        // 绑定用户角色
        Long id = user.getId();
        List<UserRole> collect = dto.getRoleIdList().stream().map(item -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(id);
            userRole.setRoleId(item);
            return userRole;
        }).collect(Collectors.toList());

        if (CollUtil.isNotEmpty(collect)) {
            userRoleService.saveAllBatch(collect);
        }
    }

    /**
     * 分页查询用户信息
     *
     * @param userListDTO
     * @return
     */
    @Override
    public Page<UserListVO> pageList(UserListDTO userListDTO) {
        Page<UserListVO> page = new Page<>(userListDTO.getPageNumber(), userListDTO.getPageSize());
        Page<UserListVO> listByPage = userMapper.findListByPage(page, userListDTO);
        List<UserListVO> records = listByPage.getRecords();
        for (UserListVO record : records) {
            Long id = record.getId();
            List<UserRoleVO> userRoleVo = userRoleService.getUserRoleVoByUserId(id);
            record.setRoles(userRoleVo);
        }
        return page;
    }

    /**
     * 修改用户信息
     *
     * @param userUpdateDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(UserUpdateDTO userUpdateDTO) {
        // 对用户表 更新账号信息
        User user = getById(userUpdateDTO.getId());
        if (user == null) {
            throw new CommonException("账号不存在！");
        }
        BeanUtils.copyProperties(userUpdateDTO, user);
        user.setModifyTime(LocalDateTime.now());
        user.updateById();

        Long userId = user.getId();
        userRoleService.delete(userId);
        List<UserRole> collect = userUpdateDTO.getRoleId().stream().map(item -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(item);
            return userRole;
        }).collect(Collectors.toList());

        if (CollUtil.isNotEmpty(collect)) {
            userRoleService.saveAllBatch(collect);
        }
    }

    /**
     * 重置密码
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void resetPassword(Long id) {
        User user = getById(id);
        if (user == null) {
            throw new CommonException("账号不存在！");
        }
        String hashpw = BCrypt.hashpw(Const.INIT_PWD);
        user.setPassword(hashpw);
        user.setModifyTime(LocalDateTime.now());
        user.updateById();
    }

    /**
     * 删除用户
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        User user = getById(id);
        if (user == null) {
            throw new CommonException("账号不存在！");
        }
        user.setState(Const.NO);
        user.setModifyTime(LocalDateTime.now());
        user.updateById();
        // 删除账号绑定角色记录
        userRoleService.delete(id);
    }

    /**
     * 切换启用状态
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void switchState(Long id) {
        User user = getById(id);
        if (user == null) {
            throw new CommonException("账号不存在！");
        }
        if (Const.NO.equals(user.getUsable())) {
            user.setUsable(Const.YES);
        } else {
            user.setUsable(Const.NO);
        }
        user.setModifyTime(LocalDateTime.now());
        user.updateById();
    }

    @Override
    public UserInfoVO currentInfo() {
        long userId = StpUtil.getLoginIdAsLong();
        User user = getById(userId);
        if (ObjectUtil.isNull(user)) {
            throw new CommonException("用户不存在");
        }
        return BeanUtil.copyProperties(user, UserInfoVO.class);
    }

}
